查看原文
其他

python脚本|云平台新增主机后,jumpserver自动导入主机信息

曾哥 大侠之运维 2023-07-22

点击上方蓝字  关注大侠之运维

jumpserver在之前几年就有使用过,之前用的没有web界面,最近在新公司也重新搭建了jumpserver,但是在主机导入上觉着有些麻烦,就看了下jumpserver对应的api,然后脚本导入相关的信息。

 

因为后面还会有新增的主机,所以每天也会去拉取云主机最新的列表,然后自动去导入到主机清单中。因为是根据系统名做了节点,所以有新的系统新增了主机,相应的节点信息也是没有的,所以会去查看节点是否存在,没有的话,也会自动建立。

 

本文中脚本内容可能不全或者不是很适应你的场景,详细的脚本内容可以后台私信获取。


♦️

认证


第一步 认证

调用jumpserver api的第一步还是要完成认证

官方也给了一些参考资料

大致分为三步

获取token--构建头信息--调用接口

这里以一个查看节点信息为例

#代码中ip根据自己的ip去替换,账户信息也根据自己的替换掉


class Jumpserver(): def get_token(self): url = 'http://ip/api/v1/authentication/auth/' query_args = { "username" : "admin", "password" : "admin", } requests.packages.urllib3.disable_warnings() response = requests.post(url,data=query_args,verify=False) #print (response.text) return json.loads(response.text)['token']
def header_info(self): #用户构建header头信息 token = self.get_token() header_info = {"Authorization": 'Bearer ' + token} #print (header_info) return header_info
def get_node_list(self):
req = requests.get('http://192.168.200.6/api/v1/assets/nodes/' , headers=self.header_info(),verify=False) node_list_json = json.loads(req.content.decode()) node_list_df = pd.DataFrame.from_records( node_list_json, columns=["id", "name", "full_value", "key"]) node_list_df["full_value"] = node_list_df["full_value"].str.replace( " ", "") #print (type(node_list_df["full_value"])) return node_list_dfif __name__ == '__main__': a = Jumpserver() b=a.get_node_list()


♦️

获取节点id,新的节点创建



因为我们的最终需求是要去创建新的ip信息,然后还要插入到已有的节点中

而不是默认的default下面,所以查看了相应的参数需求

具体api可以到 http://ip/api/docs 下面去查看

新建信息对应的api是assets

 

查看相关信息,必须的几个参数是:hostname、ip、platform

而我们前面提到的节点信息是需要具体的uuid,而不是自己拼接节点信息

所以在新插入一个信息之前,我们需要去获取对应的系统的节点信息,如果没有需要新建,并且新建好之后,还需要返回对应的值,具体的函数可以参考如下:


def get_nodeid_by_fullpath(self, fullpath): #这个是获取节点的node_id的,即通过节点的路径,获取的node_id #print (fullpath.split('[')[1].split(']')[0]) # 可以看到这个函数依赖于前面提到的查看node列表的函数 node_id = self.get_node_list()["full_value"] == fullpath #print (node_id) if node_id.any(): return self.get_node_list()[node_id]["id"].str.cat() print ('1') else: print ('节点未建立') print (fullpath) nodeid= fullpath.split('/')[3] env=fullpath.split('/')[2] print (nodeid,env) #这里对于没有建立的节点,调用了建立节点的函数,具体如下文 self.create_inode(nodeid,env) node_id = self.get_node_list()["full_value"] == fullpath #a=self.get_node_list() return self.get_node_list()[node_id]["id"].str.cat()

建立新节点函数


def create_inode(self,nodename,env): # 添加节点信息 #print (Config.prdid) #下面这串url里面的一串字符是default节点的uuid,因为我的新节点是在default下面建立的 url = 'http://ip/api/v1/assets/nodes/4c713b57-372e-4cac-994d-25ee413a46e3/children/'
nodesData = { "value":nodename,
} #nodesData = json.dumps(nodesData) print (url) nodesreq = requests.post(url, headers=self.header_info(), data=nodesData,verify=False) nodesreq = json.loads(nodesreq.text) print(nodesreq)


♦️

新建主机信息


在获取了节点id之后

就可以根据接口需要的信息去拼接对应的data来实现插入数据了

因为我这边的ssh端口都不是默认的22,所以还需要制定端口协议

另外就是特权用户也是固定的,所以也指定了,这个特权用户,可以根据导出的数据获取。

 

下面就是导入数据的函数,会传入一个列表,列表是从csv文件中读取的,因为直接用的jumpserver导入模版,所以字段比较多


def create_asset(self,n): #requests.packages.urllib3.disable_warnings() node_id = n[27] #print (node_id) node_id = node_id.split("'")[1].split("'")[0] #print (node_id) node_id = self.get_nodeid_by_fullpath(node_id) #print (node_id)

data= { "ip" : n[1], "hostname" : n[0], "protocols" : ['ssh/2922'], "is_active" : 'True', "admin_user" : n[23], "domain" : n[24], "platform" : 'Linux', "nodes" : node_id, #"nodes_display" : n[i][27], } print (n) print(n[24]) #print (data)
req = requests.post('http://ip/api/v1/assets/assets/',headers=self.header_info(),data=data,verify=False) #req = requests.get('http://30.16.27.209/api/v1/assets/assets/',headers=self.header_info(),verify=False) print (req.text) print (req.status_code) if req.status_code == 201: logging.info("%s add success" % node_id) print ("%s add success" % node_id) else: logging.info("%s fail" % node_id) print ("%s fail" % node_id)


读取csv文件,获取列表函数


def readcsv(self): data = list(csv.reader(open('test.csv','r'))) print (len(data)) for su in range(1,len(data)): self.create_asset(data[su])

♦️

生成csv文件

这个第四步其实场景就不一样了

有些是第一次导入的情况,有些是新增数据

我们目前的情况是,不时会有新增的数据,新增的数据是在云平台上的

所以需要从云平台定时来取最新的数据,然后根据创建时间来判断是否是新的数据,然后生成对应数据的csv文件,因为一直用的是jumpserver 的导入模版,所以数据列比较多。

 

这部分仅提供了生成csv的参考脚本,可以根据需要去调整自己的生成方式。


#这个里面循环的result是我们从云平台拉出数据的一个字典 for i in range(len(result['body']['content'])): values=[result['body']['content'][i]['name'],result['body']['content'][i]['portDetail'][0]['privateIp'],"Linux","['ssh/29022']","","","","","","","","","","","","","","","","","","","","","","60139add-4bee-43b8-8f1a-cb463ebe2fc5","","['/Default/sys']",""]
l1.append(values) name1=["*主机名","*IP","*系统平台","协议组","协议","端口","激活","公网IP","资产编号","备注","制造商","型号","序列号","CPU型号","CPU数量","CPU核数","CPU总数","内存","硬盘大小","硬盘信息","操作系统","系统版本","系统架构","主机名原始","网域","特权用户","节点","节点名称","标签管理"] test=pd.DataFrame(columns=name1,data=l1) #print(test) fn="jp_"+(time.strftime("%Y%m%d%H%M")+".csv")
test.to_csv(fn,encoding='gbk',index=False) #如果csv文件没问题的话,可以直接在这边去调用那边的readcsv函数,完成数据的自动导入。

♦️

总结


当时做这个的背景是因为我们新搭建了jumpserver,但是主机量有很大,又不想手动去搞,所以花了点时间去研究了下

 

目前的话,有新的主机在云平台下单了,现在就直接更新了,然后可以直接在跳板机上登录了

 

还有部分没有介绍到,因为我们还分了不同的环境,实际上特权用户也是不同的,所以特权用户、节点名称等还涉及到了一个区分。





👆点击查看更多内容👆


推荐阅读

elk8.0部署文档(rsyslog+kafka+logstash+elasticsearch+kibana))

ELK告警插件-elastalert2 实践,支持elk8.0版本,企微机器人告警实现 


记得星标记一下,下次更容易找到我

       

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存